package pentago.engine;

import java.util.ArrayList;
import java.util.Random;

//import java.util.Hashtable;

import pentago.exceptions.PentagoInvalidPlatePositionException;
import pentago.exceptions.PentagoInvalidPositionException;
import pentago.exceptions.PentagoInvalidRotationException;

public class PentagoUtils {

    public static final byte[] rotations = { Move.CLOCKWISE,
	    Move.COUNTERCLOCKWISE };
    public static final byte[] platePositions = { GameBoard.UPPER_LEFT,
	    GameBoard.UPPER_RIGHT, GameBoard.LOWER_LEFT, GameBoard.LOWER_RIGHT };

    // public static ArrayList<GameState> TTGenerateNextStates(
    // GameState currentState, Hashtable transpositionTable) {
    // ArrayList<GameState> nextStates = new ArrayList<GameState>(
    // (36 - currentState.getMarblesCount()) * 9);
    // ArrayList<Move> incompleteMovesList;
    // GameState newState;
    // Move nextMove = null;
    //
    // incompleteMovesList = currentState.generateIncompleteMoves();
    // for (Move move : incompleteMovesList) {
    // newState = currentState.nextStateFromMove(move);
    // if (newState.isTerminal()) {
    // nextStates.add(newState);
    // }
    // }
    //
    // for (Move move : incompleteMovesList) {
    // for (int platePosIndex = 0; platePosIndex < platePositions.length;
    // ++platePosIndex) {
    // for (int rotationIndex = 0; rotationIndex < rotations.length;
    // ++rotationIndex) {
    // try {
    // nextMove = new Move(move.getPosition(),
    // platePositions[platePosIndex],
    // rotations[rotationIndex]);
    // } catch (PentagoInvalidPositionException
    // | PentagoInvalidRotationException
    // | PentagoInvalidPlatePositionException e) {
    // e.printStackTrace();
    // }
    //
    // newState = currentState.nextStateFromMove(nextMove);
    // if (newState.isTerminal()
    // || transpositionTable.containsKey(newState
    // .generateHashKey())) {
    // nextStates.add(0, newState);
    // } else {
    // nextStates.add(newState);
    // }
    // }
    // }
    // }
    // return nextStates;
    // }

    public static ArrayList<GameState> generateNextStates(GameState currentState) {
	ArrayList<GameState> nextStates = new ArrayList<GameState>(
		(36 - currentState.getMarblesCount()) * 9);
	ArrayList<Move> incompleteMovesList;
	GameState newState;
	Move nextMove = null;

	incompleteMovesList = currentState.generateIncompleteMoves();
	for (Move move : incompleteMovesList) {
	    newState = currentState.nextStateFromMove(move);
	    if (newState.isTerminal()) {
		nextStates.add(newState);
	    }
	}

	for (Move move : incompleteMovesList) {
	    for (int platePosIndex = 0; platePosIndex < platePositions.length; ++platePosIndex) {
		for (int rotationIndex = 0; rotationIndex < rotations.length; ++rotationIndex) {
		    try {
			nextMove = new Move(move.getPosition(),
				platePositions[platePosIndex],
				rotations[rotationIndex]);
		    } catch (PentagoInvalidPositionException
			    | PentagoInvalidRotationException
			    | PentagoInvalidPlatePositionException e) {
			e.printStackTrace();
		    }

		    newState = currentState.nextStateFromMove(nextMove);
		    if (newState.isTerminal()) {
			nextStates.add(0, newState);
		    } else {
			nextStates.add(newState);
		    }
		}
	    }
	}
	return nextStates;
    }

    public static void randomizeMovesStates(ArrayList<Move> movesList,
	    ArrayList<GameState> statesList) {
	Random random = new Random();
	int maxIndex = movesList.size();
	int currentIndex;
	Move tempMove;
	GameState tempState;

	for (int i = 1; i < movesList.size(); ++i) {
	    currentIndex = random.nextInt(maxIndex);

	    tempMove = movesList.get(currentIndex);
	    movesList.set(currentIndex, movesList.get(maxIndex - 1));
	    movesList.set(maxIndex - 1, tempMove);

	    tempState = statesList.get(currentIndex);
	    statesList.set(currentIndex, statesList.get(maxIndex - 1));
	    statesList.set(maxIndex - 1, tempState);

	    --maxIndex;
	}

    }
}
